/**
 * Copyright 2010 Per-Erik Bergman (per-erik.bergman@jayway.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.opengl.englishwars;

import java.io.IOException;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import se.jayway.opengl.tutorial.mesh.Cube;
import se.jayway.opengl.tutorial.mesh.Group;
import se.jayway.opengl.tutorial.mesh.MyGrid;
import se.jayway.opengl.tutorial.mesh.SimplePlane;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.BitmapFactory;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

/**
 * This class is the setup for the Tutorial part VI located at:
 * http://blog.jayway.com/
 * 
 * @author Per-Erik Bergman (per-erik.bergman@jayway.com)
 * 
 */
public class EnglishWars extends Activity implements Renderer {
	// private final Group root = new Group();
	MediaPlayer mPlayer;
	private Group root;
	// Our vertex buffer.
	// private final FloatBuffer mVerticesBuffer = null;
	public long startTime = System.nanoTime();
	boolean isAnswerInputed = false;
	int mWidth, mHeight;
	Cube mCube;
	SimplePlane mPlane;
	OpenGLES10SurfaceView glView;
	EditText et;
	boolean isFocused;
	String mQuestion;
	MyDatabaseOpenHelper mDBHelper;
	Cursor mCursor = null;
	// MyButton mButton;
	SensorManager mSm;
	int mOrientCount;
	float[] mGravity = null;
	float[] mGeoMagnetic = null;
	public static float mRollValue;
	public float mPitchValue;
	GL10 mGl;
	boolean isUpdating = false;
//	float[] faBack = new float[16];
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Intent intent = getIntent();
		int song_num = intent.getIntExtra("song_num", 0);
		Log.i("Test", "select: "+song_num);
		mSm = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
		
//		mQuestion = "Somewhere, over the rainbow, way up high.";
		root = new Group();
		// Remove the title bar from the window.
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);

		// Make the windows into full screen mode.
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		setContentView(R.layout.activity_main_org);
		glView = (OpenGLES10SurfaceView) findViewById(R.id.surfaceView1);
		glView.setRenderer(this);

		// mWidth = view.getWidth();
		// mHeight = view.getHeight();

		mPlayer = new MediaPlayer();
		Button btn = (Button) findViewById(R.id.submit);
		btn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				String path = Environment.getDataDirectory().getAbsolutePath();
				Log.i("Test", "버튼클릭" + path);
				isAnswerInputed = false;

				// InputMethodManager manager = (InputMethodManager)
				// getSystemService(EnglishWars.this.INPUT_METHOD_SERVICE);
				// manager.hideSoftInputFromWindow(et.getWindowToken(), 0);
				hideSoftKeyboard();

				String answer = et.getText().toString();
				answer = ConvertUtil.removeUnusedChar(answer);
				mQuestion = ConvertUtil.removeUnusedChar(mQuestion);
//				if (mQuestion.equalsIgnoreCase(answer)) {
					new AlertDialog.Builder(EnglishWars.this).setTitle("Congraturation!!")
							.setMessage("맞았습니다!!")
							.setIcon(R.drawable.icon)
							.setPositiveButton("닫기", new DialogInterface.OnClickListener(){

								public void onClick(DialogInterface arg0,
										int arg1) {
									et.setText("");
									isUpdating = true;
									root.remove(mPlane);
									if (mCursor.moveToNext()){
										mQuestion = mCursor.getString(1);
										Log.i("Test", "다시 읽은 question:"+mQuestion);
										mPlane = new SimplePlane();
										// Load the texture.
										mPlane.loadGLTexture(mGl, BitmapFactory.decodeResource(MyApplication
												.getContext().getResources(), R.drawable.jay));
										root.add(mPlane);	
									}
									isUpdating = false;
								}
								
							})
							.show();
//				}
				Log.i("Test", answer);

			}
		});
		btn = (Button) findViewById(R.id.hear);
		btn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				playSound();
			}
		});

		et = (EditText) findViewById(R.id.answer);
		et.setOnEditorActionListener(new OnEditorActionListener() {

			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				Log.i("Test", "리턴키!!");
				return true;
			}
		});

		et.setOnTouchListener(new OnTouchListener() {

			public boolean onTouch(View v, MotionEvent event) {
				Log.i("Test", "Touched!!");
				isAnswerInputed = true;
				showSoftkeyboard();
				return true;
			}
		});
		
		mDBHelper = new MyDatabaseOpenHelper(this);
		try {
			if (mCursor != null) {
				mCursor.close();
				mCursor = null;
			}
			SQLiteDatabase db = mDBHelper.getReadableDatabase();
			String sql = "SELECT "
					+DBConstant.QuizTable.QUIZ_NUM+", "
					+DBConstant.QuizTable.SENTENCE+", "
					+DBConstant.QuizTable.HINT_WORD
					+" FROM " + DBConstant.QuizTable.TABLE_NAME
					+" WHERE " +
					DBConstant.QuizTable.SONG_NUM + " = ? ";
			String[] argument = { String.valueOf(song_num) };
			mCursor = db.rawQuery(sql, argument);
			if (mCursor.moveToNext()){
				mQuestion = mCursor.getString(1);
				Log.i("Test", "question:"+mQuestion);
			}
		} catch (Exception e) {
			Log.e("Test", e.getMessage());
		}

	}
	
	private void playSound() {
        mPlayer.reset();

		String loc = "http://translate.google.com/translate_tts?tl=en&q="+ mQuestion;
		Log.i("Test", loc);
		Uri uri = Uri.parse(loc);
		if (LoadMedia(uri)){
			try {
				mPlayer.start();
			} catch (Exception e) {
				// Toast.makeText(MyApplication.getContext(), "error : " +
				// e.getMessage(), 0).show();
			}		
		}
	}

    // 항상 준비 상태여야 한다.
    boolean LoadMedia(Uri uri) {
		try {
			mPlayer.setDataSource(EnglishWars.this, uri);
			mPlayer.prepare();
		} catch (IllegalArgumentException e) {
			return false;
		} catch (IllegalStateException e) {
			return false;
		} catch (IOException e) {
			return false;
		}

		return true;
    }
    
	private void showSoftkeyboard() {
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.showSoftInput(et, 0);
	}

	private void hideSoftKeyboard() {
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(et.getWindowToken(), 0);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.microedition
	 * .khronos.opengles.GL10, int, int)
	 */
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		mWidth = width;
		mHeight = height;
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

		gl.glViewport(0, 0, width, height);
//		gl.glMatrixMode(GL10.GL_PROJECTION);
//		gl.glLoadIdentity();
//		GLU.gluPerspective(gl, 67, width / (float) height, 0.1f, 10f);
//		GLU.gluLookAt(gl, 0, 1, 3, 0, 0, 0, 0, 1, 0);

		// // Sets the current view port to the new size.
		// gl.glViewport(0, 0, width, height);
		// // Select the projection matrix
		// gl.glMatrixMode(GL10.GL_PROJECTION);
		// // Reset the projection matrix
		// gl.glLoadIdentity();
		// // Calculate the aspect ratio of the window
		// GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,
		// 1000.0f);
		// // Select the modelview matrix
		// gl.glMatrixMode(GL10.GL_MODELVIEW);
		// // Reset the modelview matrix
		// gl.glLoadIdentity();
	}


	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		mGl = gl;
		// Set the background color to black ( rgba ).
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
		// Enable Smooth Shading, default not really needed.
		gl.glShadeModel(GL10.GL_SMOOTH);
		// Depth buffer setup.
		gl.glClearDepthf(GL10.GL_ONE);

		// Enables depth testing.
		gl.glEnable(GL10.GL_DEPTH_TEST);
		// The type of depth testing to do.
		gl.glDepthFunc(GL10.GL_LEQUAL);
		// Really nice perspective calculations.
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

		mPlane = new SimplePlane();
		// Load the texture.
		mPlane.loadGLTexture(gl, BitmapFactory.decodeResource(MyApplication
				.getContext().getResources(), R.drawable.jay));
		SimplePlane backPlane = new SimplePlane(0, 0);
		backPlane.loadGLTexture(gl, BitmapFactory.decodeResource(MyApplication
				.getContext().getResources(), R.drawable.background));
		
		MyGrid grid = new MyGrid();
		// mButton = new MyButton();
		// mButton.loadGLTexture(gl, BitmapFactory.decodeResource(MyApplication
		// .getContext().getResources(), R.drawable.button));
		root.add(mPlane);
		root.add(grid);
		root.add(backPlane);
		// root.add(mButton);
		startTime = System.nanoTime();
//		initImage(faBack, 0, 0, 320, 480, 0, 0, 512);

	}

	@Override
	public void onBackPressed() {
		Log.i("Test", "백키!!");
		super.onBackPressed();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.microedition.
	 * khronos.opengles.GL10)
	 */
	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		GLU.gluPerspective(gl, 67, mWidth / (float) mHeight, 0.1f, 15f);
		float eyeY = 1-(int)mRollValue/10;
		float eyeX= 0- (int)mPitchValue/10;
		if ( eyeY<0.3f)
			eyeY = 0.3f;
		GLU.gluLookAt(gl, eyeX, eyeY, 3, 0, 0, 0, 0, 1, 0);		
		
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		// Reset the modelview matrix
		gl.glLoadIdentity();

		// gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		// gl.glViewport(0, 0, mWidth, mHeight);
		// gl.glMatrixMode(GL10.GL_PROJECTION);
		// gl.glLoadIdentity();
		// gl.glOrthof(-1, 1, -1, 1, 10, -10);
		// gl.glMatrixMode(GL10.GL_MODELVIEW);
		// gl.glLoadIdentity();

		// gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		// gl.glViewport(0, 0, mWidth, mHeight);
		// gl.glMatrixMode(GL10.GL_PROJECTION);
		// gl.glLoadIdentity();
		// GLU.gluPerspective(gl, 67, mWidth / (float) mHeight, 0.1f, 10f);
		// gl.glMatrixMode(GL10.GL_MODELVIEW);
		// gl.glLoadIdentity();
		float deltaTime = (System.nanoTime() - startTime) / 1000000000.0f;

		if (deltaTime > (isAnswerInputed ? 5 : 3)) {
			startTime = System.nanoTime();

			root.update(1);
		}
		if (mPlane.z >9){
			root.remove(mPlane);
			mPlane = new SimplePlane();
			// Load the texture.
			mPlane.loadGLTexture(gl, BitmapFactory.decodeResource(MyApplication
					.getContext().getResources(), R.drawable.jay));
			root.add(mPlane);
		}
		if (!isUpdating){
			// Draw our scene.
			root.draw(gl);
		}

		// gl.glLoadIdentity();
		// gl.glTranslatef(3, 0, 3);
		// gl.glScalef(2, 2, 2);
		// root.draw(gl);

	}
	
    @Override
	protected void onResume() {
        super.onResume();
        Log.i("Test", "onResume() called");
		mSm.registerListener(mSensorListener, mSm.getDefaultSensor(
				Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
		mSm.registerListener(mSensorListener, mSm.getDefaultSensor(
				Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
    }
    
    @Override
	protected void onPause() {
        super.onPause();
        Log.i("Test", "onPause() called");
        mSm.unregisterListener(mSensorListener);
    }

    SensorEventListener mSensorListener = new SensorEventListener() {
		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}

		public void onSensorChanged(SensorEvent event) {
			switch (event.sensor.getType()) {
			case Sensor.TYPE_ACCELEROMETER: 
				mGravity = event.values.clone(); 
				break; 
			case Sensor.TYPE_MAGNETIC_FIELD: 
				mGeoMagnetic = event.values.clone(); 
				break; 
			}
			
			// 둘 다 조사되어 있을 때만
			if (mGravity != null && mGeoMagnetic != null) {
	            float[] R = new float[16]; 
	            SensorManager.getRotationMatrix(R, null, mGravity, mGeoMagnetic);

	            float[] values = new float[3];
	            SensorManager.getOrientation(R, values);
	            mRollValue = Radian2Degree(values[2]);
	            mPitchValue = Radian2Degree(values[1]);
//	            Log.i("Test", "pitch:" + Radian2Degree(values[1]));
//				mTxtOrient.setText("방향 = " + mOrientCount++ + "회" + 
//						"\nazimuth:" + Radian2Degree(values[0]) + 
//						"\npitch:" + Radian2Degree(values[1]) + 
//						"\nroll:" + Radian2Degree(values[2]));
			}
		}
	};
	
	float Radian2Degree(float radian) {
		return radian * 180 / (float)Math.PI;
	}
	
	public static float getRollValue() {
		return mRollValue;
	}
}